//****************************************************************************
// chainwriter.cpp
// implamentaion of the ChainWriter class.
//
// Author: Einat Zuker
//****************************************************************************
#include "chainwriter.h"

//----------------------------------------------------------------------------
// Ctor
// creates a new ChainWriter object with the file name given
//
// @param fileName
//		the name of the chain file to open for writing
//
// @throws ChainWriterExepetion
//		in case of failure in opening the file
//----------------------------------------------------------------------------
ChainWriter::ChainWriter(string fileName)
{
	//TODO what to do in case file exsits? run over or error?
	m_File.open(fileName.c_str(), std::ios::out);
	if (m_File.fail())
	{
		string failStr = "failed to open the chain dile:" + fileName;
		throw (new ChainWriterExepetion(failStr));
	}
}

//----------------------------------------------------------------------------
// Dtor
// destroys a ChainWriter object and closes the file associated with it.
// note: when closing a file it's content is flushed to the disk.
//----------------------------------------------------------------------------
ChainWriter::~ChainWriter()
{
	m_File.close();
}

//----------------------------------------------------------------------------
// SetBinaryWordLength
// writes the given length to the chain file
//
// @param n
//		the length to write to the file
//----------------------------------------------------------------------------
void ChainWriter::SetBinaryWordLength(int n)
{
	m_File<<n<<" ";
	m_BinaryWordLength = n;
}

//----------------------------------------------------------------------------
// SetBinaryWordWeight
// writes the given weight to the chain file
//
// @param w
//		the weight to write to the file
//----------------------------------------------------------------------------
void ChainWriter::SetBinaryWordWeight(int w)
{
	m_File<<w<<" ";
}

//----------------------------------------------------------------------------
// SetNumberOfGroups
// writes the given number of groups to the chain file
//
// @param newNumber
//		the number of groups to write to the file
//----------------------------------------------------------------------------
void ChainWriter::SetNumberOfGroups(int newNumber)
{
	m_File<<newNumber<<"\n";
	m_NumberOfGroups = newNumber;
}

//----------------------------------------------------------------------------
// SetGroupSummary
// writes the group Summary (all group sizes) to the chain file
//
// @param title
//		the title to give to the group summary. the title should not
//		contain any "\n" characters or ":" characters.
// @param groupSizes
//		an array of the group sizes. the first group size in the array should
//		match the first group in the file and so on until the last group.
//----------------------------------------------------------------------------
void ChainWriter::SetGroupSummary(string title, int* groupSizes)
{
	m_File<< title <<": ";
	
	if(groupSizes != NULL)
	{
		for(int i=0; i < m_NumberOfGroups; i++)
		{
			m_File<<groupSizes[i]<<" ";
		}
	}

	m_File<<"\n";
}

//----------------------------------------------------------------------------
// SetFirstVertex
// writes the group id to the file and the first vertex of that group
//
// @param groupId
//		the group id that we want to add to the file
// @param vertexName
//		a pointer to a vertex name that is the first vertex of the group
//		with the id: groupId
//----------------------------------------------------------------------------
void ChainWriter::SetFirstVertex(int groupId, vector<bool> *vertexName)
{
	m_File<<"\n"<<"# "<<groupId<<"\n";

	if(vertexName != NULL)
	{
		for(int i=0; i < m_BinaryWordLength; i++)
		{
			m_File<<(*vertexName)[i];
		}
	}
	
	m_File<<"\n";
}

//----------------------------------------------------------------------------
// SetNextVertex
// writes the next vertex in the group to the file.
// note: this function should only be called after calling SetFirstVertex
//
// @param vertexName
//		a pointer to a vertex name that is the vertex we want to write
//		to the file.
//----------------------------------------------------------------------------
void ChainWriter::SetNextVertex(vector<bool> *vertexName)
{
	if (vertexName != NULL)
	{
		for(int i=0; i < m_BinaryWordLength; i++)
		{
			m_File<<(*vertexName)[i];
		}
	}
	
	m_File<<"\n";
}
